<?php

declare(strict_types=1);
/**
 * 小程序用户业务层
 * User：Abell
 * Date：2020/5/25
 */

namespace App\Service;

use App\Extend\Wx\Wxlogin;
use App\JsonRpc\ServiceConsumer\UserAmountServiceInterface;
use App\Utils\{StringUtil,ServerUtil};
use Hyperf\Utils\Context;
use App\Dao\{LotteryDao,WxuserDao,AdminLogDao};
use App\Constants\ErrorCode;
use App\Lib\JwtToken;
use Psr\Container\ContainerInterface;
use Hyperf\Di\Annotation\Inject;
//支付宝登录
use App\Extend\Ali\AliSdk;

class WxuserService
{
    /**
     * @Inject
     * @var ContainerInterface
     */
    protected $container;

    /** 打开html获取用户信息
     * @Author abell
     * @DateTime 2020-06-13
     * @return
     */
    public function getUserInfo(){
        $result = make(AliSdk::class)->userReg();
        return $result;
    }


    /** 支付宝小程序授权保存用户信息
     * @Author abell
     * @DateTime 2020-06-09
     * @return
     */
    public function saveAliUser($request){
        // 通过code获取user_id
        $token_array = $this->getToken($request);
        if($token_array['errCode']){
            //获取token失败
            return $token_array;
        }else{
            // 查询用户是否存在
            $openid = $token_array['alipay_system_oauth_token_response']['user_id'];
            $has_user = make(WxuserDao::class)->getUser($openid);
            $request_array = json_decode($request['user_info']);
            // 处理保存用户数据
            $user_json_array = [
                'avatar' => $request_array['avatar'],
                'city' => $request_array['city'],
                'countryCode' => $request_array['countryCode'],
                'gender' => ($request_array['gender'] == 'm') ? 1 : 0,
                'nickName' => $request_array['nickName'],
                'province' => $request_array['province'],
                'user_type' => 2,
                'openid' => $openid
            ];
            if($has_user){
                // 用户已存在,更新用户信息
                $save_user = make(WxuserDao::class)->updateUserInfo(['openid'=>$openid],$user_json_array);
            }else{
                // 用户不存在,创建用户
                $save_user = make(WxuserDao::class)->saveUserInfo($user_json_array);
            }
            return $save_user;
        }
    }

    /** 支付宝小程序通过code获取token
     * @Author abell
     * @DateTime 2020-06-11
     * @return
     */
    public function getToken($request){
        $result = make(AliSdk::class)->getToken($request['code']);
        // 处理token数据
        $result_array = json_decode(json_encode($result),true);
        $error_data = array_key_exists('error_response',$result_array);
        $result_array['msg'] = 'ok';
        $result_array['errCode'] = ErrorCode::SUCCESS;
        if($error_data){
            $result_array['msg'] = $result_array['error_response']['sub_msg'];
            $result_array['errCode'] = ErrorCode::ERR_BUESSUS;
        }
        return $result_array;
    }

    /**
     * 用户全国地图
     * @Author abell
     * @DateTime 2020-05-26
     * @param array $request
     * @return array
     */
    public function mapInfo(){
        // 根据省来获取对应的人数
        $result = make(WxuserDao::class)->userMap();
        $provinces = make(WxuserDao::class)->mapInfo(['level_type'=>1],['province_pinyin','short_name','province']);
        $result_column = array_column($result,null,'province');
        $return_array = array();
        foreach ($provinces as $province_name) {
            $province_count = 0;
            // 判断省拼音是否存在记录
            if(array_key_exists($province_name['province_pinyin'],$result_column)){
                $province_count = $province_count + $result_column[$province_name['province_pinyin']]->count;
            }
            if(array_key_exists($province_name['short_name'],$result_column)){
                $province_count = $province_count + $result_column[$province_name['short_name']]->count;
            }
            // 判断修改钓鱼岛
            if($province_name['short_name'] == '钓鱼岛') {
                array_push($return_array,['name'=>'南海诸岛','value'=>$province_count]);
            }else{
                array_push($return_array,['name'=>$province_name['short_name'],'value'=>$province_count]);
            }
        }
        return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$return_array];
    }

    /**
     * 小程序用户编辑信息查看
     * @Author abell
     * @DateTime 2020-05-26
     * @param array $request
     * @return array
     */
    public function userEditInfo($request){
        $user_info = make(WxuserDao::class)->getUser('',['*'],$request['id']);
        $user_info->nickname = make(StringUtil::class)->strIsBase64($user_info->nickname);
        return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$user_info];
    }

    /**
     * 小程序用户编辑信息提交
     * @Author abell
     * @DateTime 2020-05-26
     * @param array $request
     * @return array
     */
    public function userEditSave($request){
        try {
            $before_data = make(WxuserDao::class)->getUser('',['*'],$request['id']);
            // post 修改用户信息
            $update_data['update_time'] = time();
            if(array_key_exists('nickname',$request)) $update_data['nickname'] = base64_encode($request['nickname']);
            if(array_key_exists('avatarurl',$request)) $update_data['avatarurl'] = $request['avatarurl'];
            if(array_key_exists('gender',$request)) $update_data['gender'] = $request['gender'];
            if(array_key_exists('country',$request)) $update_data['country'] = $request['country'];
            if(array_key_exists('province',$request)) $update_data['province'] = $request['province'];
            if(array_key_exists('city',$request)) $update_data['city'] = $request['city'];
            if(array_key_exists('language',$request)) $update_data['language'] = $request['language'];
            if(array_key_exists('mobile',$request)) $update_data['mobile'] = $request['mobile'];
            if(array_key_exists('haspay',$request)) $update_data['haspay'] = $request['haspay'];
            $update_user = make(WxuserDao::class)->updateUserInfo(['id'=>$request['id']],$update_data);
            make(AdminLogDao::class)->addLog('编辑了微信信息,改前数据“'.json_encode($before_data).'”'.'改后数据“'.json_encode($update_data).'”');
            return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$update_user];
        }catch (\Exception $e) {
            ServerUtil::info('获取小程序用户信息编辑/admin/wxuser/user_edit', ['error' => $e->getMessage(), 'request' => $request], 'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }
    }

    /**
     * 小程序用户列表
     * @Author abell
     * @DateTime 2020-05-26
     * @param array $request
     * @return array
     */
    public function userList($request){
        try {
            $pageSize = array_key_exists('pageSize',$request) ? $request['pageSize'] : 15 ;
            $pageNum = array_key_exists('page',$request) ? (int)$request['page'] : 1 ;
            $order = array_key_exists('order',$request) ? $request['order'] : 'add_time desc';
            if(array_key_exists('pid',$request)){
                if(array_key_exists('nickname',$request)){
                    $result = make(WxuserDao::class)->pidGetOpenids($request['pid'],$order,$pageSize,$pageNum,$request['nickname']);
                }else{
                    $result = make(WxuserDao::class)->pidGetOpenids($request['pid'],$order,$pageSize,$pageNum);
                }
            }else{
                if(array_key_exists('nickname',$request)){
                    $result = make(WxuserDao::class)->getUsersByOpenids($order,$pageSize,$pageNum,$request['nickname']);
                }else{
                    $result = make(WxuserDao::class)->getUsersByOpenids($order,$pageSize,$pageNum);
                }
            }
            if(!$result['total']) return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>[]];
            $openid_arr = array_column($result['data'],'openid');
            $openids_str = implode(',',$openid_arr);
            $client = $this->container->get(UserAmountServiceInterface::class);
            $msg = $client->useRecharge(json_encode(['openid'=>$openids_str,'type'=>1]));
            $msg_json = json_decode($msg,true);
            $msg_array = $msg_json['data'];
//            $msg_json['errCode'] = 0;  $msg_array = [];
            //        判断jsonRPC获取是否成功
            if($msg_json['errCode'] || (count($msg_array) == 0) ){
                // 获取数据为空,初始化数组
                foreach ($result['data'] as &$user_data) {
                    // 呢称base64解码
                    $user_data['nickname'] = make(StringUtil::class)->strIsBase64($user_data['nickname']);
                    if(empty($user_data['pid'])){
                        $user_data['pnickname'] = '';
                    }else{
                        // 查询父类呢称
                        $f_user_nickname = make(WxuserDao::class)->getUser($user_data['pid'],'nickname');
                        $user_data['pnickname'] = make(StringUtil::class)->strIsBase64($f_user_nickname->nickname);
                    }
                    $user_data['cost_amount'] = $user_data['oil_amount'] = $user_data['amount'] = 0;
                }
            }else{
                // 解析处理数据
                foreach ($result['data'] as &$user_data) {
                    // 呢称base64解码
                    $user_data['nickname'] = make(StringUtil::class)->strIsBase64($user_data['nickname']);
                    if(empty($user_data['pid'])){
                        $user_data['pnickname'] = '';
                    }else{
                        // 查询父类呢称
                        $f_user_nickname = make(WxuserDao::class)->getUser($user_data['pid'],'nickname');
                        $user_data['pnickname'] = make(StringUtil::class)->strIsBase64($f_user_nickname->nickname);
                    }
                    if(array_key_exists($user_data['openid'],$msg_array)){
                        $user_data['cost_amount'] = array_key_exists('cost_amount',$msg_array[$user_data['openid']]) ? $msg_array[$user_data['openid']]['cost_amount'] : 0 ;
                        $user_data['oil_amount'] = array_key_exists('oil_amount',$msg_array[$user_data['openid']]) ? $msg_array[$user_data['openid']]['oil_amount'] : 0 ;
                        $user_data['amount'] = $user_data['cost_amount'] + $user_data['oil_amount'];
                    }else{
                        $user_data['cost_amount'] = $user_data['oil_amount'] = $user_data['amount'] = 0;
                    }
                }
            }
            return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$result];
        }catch (\Exception $e){
            ServerUtil::info('MySQL数据库连接失败获取小程序用户信息列表/admin/wxuser/user_list',['error'=>$e->getMessage(),'request'=>$request],'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }
    }

    /**
     * 通过openids获取用户信息
     * @Author abell
     * @DateTime 2020-05-28
     * @return array
     */
    public function getUserInfoByOpenids($openids,$select_str){
        try {
            $openids_list = explode(',',$openids);
            $select_list = explode(',',$select_str);
            $result = make(WxuserDao::class)->getUserByKeys('openid',$openids_list,$select_list);
            if(strstr($select_str,'nickname')){
                foreach ($result as &$ret) {
                    $ret['nickname'] = make(StringUtil::class)->strIsBase64($ret['nickname']);
                }
            }
            return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$result];
        }catch (\Exception $e){
            ServerUtil::info('通过openids获取用户信息/admin/wxuser/get_user',['error'=>$e->getMessage(),'request'=>$openids],'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }
    }

    /**
     * 小程序授权信息API
     * @Author abell
     * @DateTime 2020-05-26
     * @param array $request
     * @return array
     */
    public function login($request){
        try {
            $obj = make(Wxlogin::class)->getOpenId($request['code']);
            if($obj){
                $data_json = json_decode($obj[2], true);
                if (array_key_exists('errcode', $data_json)) {
                    return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>$data_json['errmsg']];
                }else{
                    $has_user = make(WxuserDao::class)->hasUser($data_json['openid']);
                    if($has_user){
                        $update_user = make(WxuserDao::class)->updateUserInfo(['openid'=>$data_json['openid']],['update_time' => time()]);
                    }else{
                        $update_data = ['add_time'=>time(),'update_time'=>time(),'openid'=>$data_json['openid']];
                        if(array_key_exists('pid',$request)  && ($request['pid'] != $data_json['openid'])){
                            $update_data['pid'] = $request['pid'];
                        }
                        $update_user = make(WxuserDao::class)->saveUserInfo($update_data);
                    }
                    // 记录统计记录并返回token
                    $has_visit = make(WxuserDao::class)->hasVisit($data_json['openid']);
                    $update_visit = $has_visit ? $has_visit : make(WxuserDao::class)->addVisit($data_json['openid']);
                    $token = JwtToken::authorizations((int)$update_user,$data_json['openid'],'2');
                    return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>[
                        'update_user'=>$update_user,'update_visit'=>$update_visit,'token'=>$token,'openid'=>$data_json['openid']]];
                }
            }
        }catch (\Exception $e){
            ServerUtil::info('小程序new登录注册接口/api/wxuser/loginnew',['error'=>$e->getMessage(),'request'=>$request],'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }

    }
    /**
     * 小程序授权信息API
     * @Author abell
     * @DateTime 2020-05-26
     * @param array $request
     * @return array
     */
    public function loginInfo($request){
        try {
            $has_user = make(WxuserDao::class)->hasUser($request['openid']);
            $user_info_array = json_decode($request['rawData'],true);
            $update_data = ['update_time' => time()];
            if (array_key_exists('nickName', $user_info_array)) $update_data['nickname'] = base64_encode($user_info_array['nickName']);
            if (array_key_exists('avatarUrl', $user_info_array)) $update_data['avatarurl'] = $user_info_array['avatarUrl'];
            if (array_key_exists('gender', $user_info_array)) $update_data['gender'] = $user_info_array['gender'];
            if (array_key_exists('country', $user_info_array)) $update_data['country'] = $user_info_array['country'];
            if (array_key_exists('province', $user_info_array)) $update_data['province'] = $user_info_array['province'];
            if (array_key_exists('city', $user_info_array)) $update_data['city'] = $user_info_array['city'];
            if (array_key_exists('language', $user_info_array)) $update_data['language'] = $user_info_array['language'];
            if (array_key_exists('mobile', $user_info_array)) $update_data['mobile'] = $user_info_array['mobile'];
            if($has_user){
                // 用户信息存在,更新信息
                $update_user = make(WxuserDao::class)->updateUserInfo(['openid'=>$request['openid']],$update_data);
            }else{
                // 创建用户数据
                $update_data['add_time'] = time();
                $update_data['openid'] = $request['openid'];
                if(array_key_exists('pid',$request)  && ($request['pid'] != $request['openid'])){
                    $update_data['pid'] = $request['pid'];
                }
                $update_user = make(WxuserDao::class)->saveUserInfo($update_data);
            }
            $has_visit = make(WxuserDao::class)->hasVisit($request['openid']);
            $update_visit = $has_visit ? $has_visit : make(WxuserDao::class)->addVisit($request['openid']);
            return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>[
                'user_info'=>$user_info_array,'update_user'=>$update_user,'update_visit'=>$update_visit,]];
        }catch (\Exception $e){
            ServerUtil::info('小程序二次授权接口/api/wxuser/logininfo',['error'=>$e->getMessage(),'request'=>$request],'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }
    }

    /**
     * 分享查询
     * @Author abell
     * @DateTime 2020-05-26
     * @param array $request
     * @return array
     */
    public function share($request){
        try {
            if(array_key_exists('openid',$request)){
                $has_user = make(WxuserDao::class)->getUser($request['openid']);
                $has_user->nickname = make(StringUtil::class)->strIsBase64($has_user->nickname);
                return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$has_user];
            }else{
                $jwt = Context::get('jwt_token');
                $has_user = make(WxuserDao::class)->getUser($jwt['account']);
                $has_user->nickname = make(StringUtil::class)->strIsBase64($has_user->nickname);
                return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$has_user];
            }
        }catch (\Exception $e){
            ServerUtil::info('小程序分享查询接口/api/wxuser/share',['error'=>$e->getMessage()],'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }
    }

    /**
     * 添加小程序API
     * @Author abell
     * @DateTime 2020-05-26
     * @return array
     */
    public function addsmall(){
        try {
            $jwt = Context::get('jwt_token');
            $has_add = make(WxuserDao::class)->hasAdd($jwt);
            if($has_add){
                return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$has_add];
            }else{
                $add_small = make(WxuserDao::class)->addSmall($jwt);
                return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$add_small];
            }
        }catch (\Exception $e){
            ServerUtil::info('添加小程序接口/api/wxuser/addsmall',['error'=>$e->getMessage()],'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }
    }

    /**
     * 访问记录添加API
     * @Author abell
     * @DateTime 2020-05-26
     * @return array
     */
    public function record($request){
        try {
            $jwt = Context::get('jwt_token');
            if(make(WxuserDao::class)->hasTypeExplain($request['type_explain'],$jwt['account'])){
                return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>1];
            }else{
                $result = make(WxuserDao::class)->addTypeExplain($request['type_explain'],$jwt['account']);
                return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$result];
            }
        }catch (\Exception $e){
            ServerUtil::info('小程序页面访问统计接口/api/wxuser/record',['error'=>$e->getMessage(),'request'=>$request],'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }
    }

    /**
     * 小程序签到接口API
     * @Author abell
     * @DateTime 2020-05-26
     * @return array
     */
    public function sign(){
        try {
            //传入参数token
            $jwt = Context::get('jwt_token');
            $has_sign = make(WxuserDao::class)->hasSign($jwt['account']);
            if($has_sign){
                $msg = '您今天已经签到过了,请明天再来';
            }else{
                make(WxuserDao::class)->addSign($jwt['account']);
                // 签到成功,增加一次抽奖机会
                $lottery_data = ['openid'=>$jwt['account'],
                    'type'=>1,
                    'count'=>1,
                    'remark'=>'签到成功',
                    'remark_desc' => '',
                    'order_no' => '',
                    'prize_id' => 0];
                $has_sign = make(LotteryDao::class)->addLottery($lottery_data);
                $msg = '签到成功,增加一次抽奖机会';
            }
            return ['code'=>ErrorCode::SUCCESS,'msg'=>$msg,'data'=>$has_sign];
        }catch (\Exception $e){
            ServerUtil::info('小程序签到接口数据失败/api/wxuser/sign',['error'=>$e->getMessage()],'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }
    }

    /**
     * 小程序签到状态查询API
     * @Author abell
     * @DateTime 2020-05-26
     * @return array
     */
    public function signCheck(){
        try {
            $jwt = Context::get('jwt_token');
            $has_sign = make(WxuserDao::class)->hasSign($jwt['account']);
            return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$has_sign];
        }catch (\Exception $e){
            ServerUtil::info('小程序签到接口数据失败/api/wxuser/sign_check',['error'=>$e->getMessage()],'ERROR');
            return ['code'=>ErrorCode::ERR_SERVER,'msg'=>ErrorCode::getMessage(ErrorCode::ERR_SERVER),'data'=>''];
        }
    }
}
